#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <pthread.h>
#include <errno.h>

//pointer mangling definition
#include "mangling.h"

// Input data for each Thread
typedef struct {

    int utId;               //Thread id
    char *data;             //Some data

} utInputData_t;


// Scheduler context
typedef struct {
    jmp_buf env;            //environment for setjmp/longjmp
    int (*func)(void *);    //pointer to thread function
    void *arg;              //arguments = local data
    int running;            //current state: start, running, finished
} utContext_t;


// global data

// number of LWPs in our test program
#define MAX_LWPS 2
// max number of threads in out test programm
#define MAX_THREADS 100

// scheduling context: threads are assigned to LWPs
extern utContext_t utArray[MAX_LWPS][MAX_THREADS];
// initialize thread ids
extern int utNum[MAX_LWPS];
// initialize current thread: first user space thread in first LWP
extern int utCurrent[MAX_LWPS];
// array of LWPs running
extern pthread_t lwpIdx2Id[MAX_LWPS];

// function prototypes

// create user space thread context, call for each thread before 
// scheduler is started
void utMakeContext(utContext_t *uctx, 
                   int (*func)(void *), 
                   int sk_size,
                   void *arg);

// user space thread scheduler, call after each thread has been
// registered
void *utSchedule(void *pData);

// give cpu to next thread, call to allow user space scheduling 
// whenever fitting
void utYield(int lwpIdx);


